home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / ingres04.lzh / source / ctlmod / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-24  |  7.2 KB  |  350 lines

  1. # include    <stdio.h>
  2. # include    <signal.h>
  3. # include    "ctlmod.h"
  4. # include    "pipes.h"
  5. # include    <resp.h>
  6. # include    <ingres.h>
  7. # include    <aux.h>
  8. # include    <lock.h>
  9.  
  10.  
  11. /*
  12. **  MAIN -- initialize control module
  13. **
  14. **    Called only once, this routine sets everything up.
  15. **
  16. **    The format of the argv is as follows:
  17. **        argv[0] -- pathname
  18. **        argv[1] -- file descriptor for input pipe or'ed with
  19. **            0100 to make it printable in a 'ps'.
  20. **        argv[2] -- Fileset
  21. **        argv[3] -- Usercode
  22. **        argv[4] -- Database
  23. **        argv[5] -- Pathname
  24. **
  25. **    Parameters:
  26. **        argc, argv -- as usual
  27. **
  28. **    Returns:
  29. **        none
  30. **
  31. **    Side Effects:
  32. **        Many; see code.
  33. **        Proc_name is set to the working process name.
  34. **        Fileset, Database, Usercode -- set from argv.
  35. **        Trace vectors are initialized.
  36. **
  37. **    Requires:
  38. **        markopen -- to mark the open files.
  39. **        The input pipe must have the Cm struct in it as
  40. **            the first data.
  41. **
  42. **    Trace Flags:
  43. **        1
  44. */
  45.  
  46. struct resp    Resp;        /* State response structure */
  47. struct _cm_t    Cm;        /* the system topography map */
  48. struct _ctx_t    Ctx;        /* the current context */
  49. int        Syncs[CM_MAXPROC];/* expected SYNC's from each proc */
  50.  
  51. /* General System Information */
  52. char        *Proc_name;    /* the 'name' of the currently running proc */
  53. char        *Fileset;    /* a unique string to make filenames from */
  54. char        *Database;    /* the name of the current database */
  55. char        *Usercode;    /* the code of the current user */
  56. char        *Pathname;    /* the pathname of the root of INGRES */
  57. int        Equel;        /* set if running an Equel program */
  58. int        RubLevel;    /* rubout level, -1 if ignored */
  59. extern struct out_arg    Out_arg;    /* output arguments */
  60. jmp_buf        CmReset;    /* restart addr on interrupt */
  61. # ifdef xMONITOR
  62. struct monitor    CmMonBuf;    /* monitor buffer for CM overhead */
  63. # endif xMONITOR
  64.  
  65. void
  66. main(argc, argv)
  67. int    argc;
  68. char    **argv;
  69. {
  70.     register int    i;
  71.     struct fn_def    *f;
  72.     register char    **q;
  73.     register char    *p;
  74.     pb_t        pb;
  75.     static int    reenter;
  76.     extern    void    rubcatch();
  77.     extern        error();
  78.     bool        nobuffer;
  79.     extern pb_t    *MonPpb;
  80.     extern long    CmOfiles;    /* defined in markopen.c */
  81.     int        lock_type = -1;    /* type of data base lock to request */
  82.     int        wait_action = -1;    /* type of wait action on the data abse */
  83.     char        *args;     /* used to process args of sysmod */
  84.     int        j;
  85.  
  86.     Ctx.ctx_name = Proc_name = argv[0];
  87.     argv[argc] = NULL;
  88.     nobuffer = tTrace(argv, argv[1][1], FuncVect[0]->fn_tvect, 30);
  89.     Ctx.ctx_tvect = tT;
  90.     reenter = 0;
  91.     setjmp(CmReset);
  92.     if (reenter++)
  93.         exit(-1);
  94.     if (signal(SIGINT, SIG_IGN) == SIG_DFL)
  95.         signal(SIGINT, rubcatch);
  96.     else
  97.         RubLevel = -1;
  98.     MonPpb = &pb;
  99.  
  100.     /* mark all currently open files */
  101.     acc_init();
  102.     markopen(&CmOfiles);
  103.  
  104.     /*
  105.     **  Process argument vector.
  106.     **    The easy ones just involve saving a pointer.
  107.     **    argv[1] is used to get a file descriptor; this
  108.     **        becomes the initial input.  This file
  109.     **        is read to fill in the Cm (configuration)
  110.     **        structure.
  111.     */
  112.  
  113.     if (tTf(1, 0) || argc < 6)
  114.         prargs(argc, argv);
  115.         
  116.     if (argc < 6)
  117.         syserr("main: argc=%d", argc);
  118.     q = &argv[2];
  119.     Fileset = *q++;
  120.     Usercode = *q++;
  121.     Database = *q++;
  122.     Pathname = *q++;
  123.  
  124.     i = read(argv[1][0] & 077, (char *) &Cm, sizeof Cm);
  125.     if (i != sizeof Cm)
  126.         syserr("main: read %d", i);
  127.  
  128.  
  129.     /* set up other globals */
  130.     Ctx.ctx_name = Proc_name = Cm.cm_myname;
  131.     initbuf(Qbuf, QbufSize, ERR_QBUF, error);
  132.     Ctx.ctx_cmark = Ctx.ctx_pmark = markbuf(Qbuf);
  133.  
  134.     
  135.     if ( !sequal( Proc_name, "SYSMOD"))
  136.     {
  137.         /* process flags */
  138.         for (; (p = *q) != NULL; q++)
  139.         {
  140.             if (p[0] != '-')
  141.                 continue;
  142.             switch (p[1])
  143.             {
  144.               case 'l':    /* Lock type */
  145.                 if ( Alockdes < 0 )
  146.                     break;
  147.                 if ( p[2] < '0' || p[2] > '9' )
  148.                     syserr("Illegal lock number %s",&p[2]);
  149.                 lock_type = atoi(&p[2]);
  150.                 if ( wait_action < 0 )
  151.                     break;
  152.                 if ( setdbl(wait_action,lock_type) < 0 )
  153.                 {
  154.                     syserr("Data base temporarily unavailable");
  155.                 }
  156.                 break;
  157.               case 'W':
  158.                 /*
  159.                 ** type of data base wait to preform
  160.                 */
  161.                 if ( Alockdes < 0 )
  162.                     break;
  163.                 if ( p[2] < '0' || p[2] > '9' )
  164.                     syserr("Illegal wait action %s",&p[2]);
  165.                 wait_action = atoi(&p[2]);
  166.                 if ( lock_type < 0 )
  167.                     break;
  168.                 if ( setdbl(wait_action,lock_type) < 0 )
  169.                 {
  170.                     syserr("Data base temporarily unavailable");
  171.                 }
  172.                 break;
  173.               case '&':    /* equel program */
  174.                 Equel = 1;
  175.                 if (p[6] != '\0')
  176.                     Equel = 2;
  177.                 break;
  178.     
  179.               case 'c':    /* c0 sizes */
  180.                 Out_arg.c0width = atoi(&p[2]);
  181.                 break;
  182.     
  183.               case 'i':    /* iNsizes */
  184.                 switch (p[2])
  185.                 {
  186.     
  187.                   case '1':
  188.                     Out_arg.i1width = atoi(&p[3]);
  189.                     break;
  190.     
  191.                   case '2':
  192.                     Out_arg.i2width = atoi(&p[3]);
  193.                     break;
  194.     
  195.                   case '4':
  196.                     Out_arg.i4width = atoi(&p[3]);
  197.                     break;
  198.     
  199.                 }
  200.                 break;
  201.     
  202.               case 'f':    /* fN sizes */
  203.                 p = &p[3];
  204.                 i = *p++;
  205.                 while (*p != '.')
  206.                     p++;
  207.                 *p++ = 0;
  208.                 if ((*q)[2] == '4')
  209.                 {
  210.                     Out_arg.f4width = atoi(&(*q)[4]);
  211.                     Out_arg.f4prec = atoi(p);
  212.                     Out_arg.f4style = i;
  213.                 }
  214.                 else
  215.                 {
  216.                     Out_arg.f8width = atoi(&(*q)[4]);
  217.                     Out_arg.f8prec = atoi(p);
  218.                     Out_arg.f8style = i;
  219.                 }
  220.                 *--p = '.';    /* restore parm for dbu's */
  221.                 break;
  222.     
  223.               case 'v':    /* vertical seperator */
  224.                 Out_arg.coldelim = p[2];
  225.                 break;
  226.     
  227.             }
  228.         }
  229.     
  230.     }
  231.         /* set up trace flags */
  232.         for (i = 0; i < NumFunc; i++)
  233.         {
  234.             f = FuncVect[i];
  235.             if (f->fn_tflag != '\0')
  236.                 nobuffer |= tTrace(argv, f->fn_tflag, f->fn_tvect, f->fn_tsize);
  237.             Ctx.ctx_name = Proc_name = f->fn_name;
  238.             (*f->fn_initfn)(argc, argv);
  239.         }
  240.     /* end of ingres flags */
  241.  
  242.     /*
  243.     **  Buffer standard output
  244.     **
  245.     **    Since VM/UNIX always buffers, we force non-buffered
  246.     **    output if any trace flags are set.
  247.     */
  248.  
  249.     if (!nobuffer)
  250.         set_so_buf();
  251.     else
  252.         setbuf(stdout, NULL);
  253.  
  254.     /* if Equel, tell the program to go ahead */
  255.     if (Equel && Cm.cm_myproc == 1)
  256.     {
  257.         pb_prime(&pb, PB_REG);
  258.         pb.pb_st = PB_FRONT;
  259.         pb_flush(&pb);
  260.     }
  261.  
  262.     /*
  263.     **  Start executing routines.
  264.     **
  265.     **    Do_seq knows to exit if we get an EOF on the input pipe.
  266.     */
  267.  
  268.     i = setjmp(CmReset);
  269. # ifdef xMONITOR
  270.     markperf(&CmMonBuf);
  271. # endif xMONITOR
  272.     initbuf(Qbuf, QbufSize, ERR_QBUF, error);
  273.     clrmem((char *) &Ctx, sizeof Ctx);
  274.     Ctx.ctx_cmark = Ctx.ctx_pmark = markbuf(Qbuf);
  275.     Ctx.ctx_name = Proc_name = Cm.cm_myname;
  276.     Ctx.ctx_tvect = tT = FuncVect[0]->fn_tvect;
  277. # ifdef xCTR2
  278.     if (tTf(1, 1))
  279.         lprintf("main: setjmp: %d\n", i);
  280. # endif
  281.     if (RubLevel >= 0)
  282.         signal(SIGINT, rubcatch);
  283.     closeall(FALSE, CmOfiles);
  284.     for (;;)
  285.     {
  286.         Cm.cm_input = Cm.cm_rinput;
  287.         pb.pb_st = PB_UNKNOWN;
  288.         do_seq(&pb);
  289.     }
  290. }
  291. /*
  292. **  RUBPROC -- process rubout signals
  293. **
  294. **    This routine does the processing needed on rubouts
  295. **    when running with the control module.  It basically
  296. **    flushes pipes.
  297. **
  298. **    Parameters:
  299. **        none.
  300. **
  301. **    Returns:
  302. **        never
  303. **
  304. **    Side Effects:
  305. **        Flushes pipes, etc.
  306. */
  307.  
  308. rubproc()
  309. {
  310.     register int    i;
  311.     pb_t        pb;
  312.     register int    stat;
  313.  
  314.     /*
  315.     **  Update the world for consistency.
  316.     */
  317.  
  318.     fflush(stdout);
  319.     closecatalog(FALSE);
  320.     i = pageflush(NULL);
  321.     if (i != 0)
  322.         syserr("rubproc: pageflush %d", i);
  323.  
  324.     /*
  325.     **  Send SYNC blocks to all processes that are adjacent
  326.     **    in the write direction.
  327.     **  Arrange to ignore blocks from all processes that
  328.     **    are adjacent in the read direction.
  329.     */
  330.  
  331.     pb_prime(&pb, PB_SYNC);
  332.     for (i = 0; i < CM_MAXPROC; i++)
  333.     {
  334.         stat = Cm.cm_proc[i].pr_stat;
  335.         if ((stat & PR_RADJCT) != 0)
  336.             Syncs[i]++;
  337.         if ((stat & PR_WADJCT) != 0)
  338.         {
  339.             pb.pb_proc = i;
  340.             pb_write(&pb);
  341.         }
  342.     }
  343.  
  344.     /*
  345.     **  Cleanup and exit.
  346.     */
  347.  
  348.     cm_cleanup(2);
  349. }
  350.